package xyz.hzxiao.service.impl;

import cn.novelweb.tool.http.Result;
import cn.novelweb.tool.upload.local.LocalUpload;
import cn.novelweb.tool.upload.local.pojo.UploadFileParam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import xyz.hzxiao.config.FileUploadConfig;
import xyz.hzxiao.controller.FileUploadController;
import xyz.hzxiao.pojo.UploadSuccessVO;
import xyz.hzxiao.service.FileUploadService;
import xyz.hzxiao.utils.AppResult;
import xyz.hzxiao.utils.NovelWebUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.File;

/**
 * 文件上传实现类
 *
 * @author ：FuXx
 * @className : xyz.hzxiao.service.impl.FileUploadServiceImpl
 * @since ：2023/3/7
 */
@Service("fileUploadServiceImpl")
public class FileUploadServiceImpl implements FileUploadService {

    private static final Logger LOGGER = LoggerFactory.getLogger(FileUploadController.class);

    /**
     * 每次分块大小（1M）,要与客户端端传过来的大小一致
     */
    public static final int CHUNK_SIZE = 1 * 1024 * 1024;

    @Resource(name = "fileUploadConfig")
    private FileUploadConfig config;

    /**
     * 检查文件MD5（文件MD5若已存在进行秒传）
     *
     * @param md5      文件md5
     * @param fileName 文件名称
     */
    @Override
    public AppResult<?> checkFileMd5(String md5, String fileName) throws Exception {
        Result<?> result = LocalUpload.checkFileMd5(md5, fileName, config.getConfFilePath(), config.getLocalFilePath());
        return NovelWebUtils.forReturn(result);
    }

    /**
     * 断点续传（分片）方式上传文件：用于大文件上传
     *
     * @param param   参数
     * @param request 请求对象
     */
    @Override
    public AppResult<?> shardingUploadFile(UploadFileParam param, HttpServletRequest request) throws Exception {
        Result<?> result = LocalUpload.fragmentFileUploader(param, config.getConfFilePath(), config.getLocalFilePath(), CHUNK_SIZE, request);
        return NovelWebUtils.forReturn(result);
    }

    /**
     * 分片上传完成后对文件的操作，参数可以按业务自定义
     * 这里单独去原文件名称
     *
     * @param vo 参数
     * @return 操作完成
     */
    @Override
    public AppResult<String> uploadSuccess(UploadSuccessVO vo) {
        // 分片保存的原始文件
        String sourceFileName = vo.getSourceFileName();
        File file = new File(config.getLocalFilePath().concat(sourceFileName));
        // do save to oss server or ......

        // 如果上传文件只能播放一秒，可以加入此行代码
        // try {TimeUnit.MILLISECONDS.sleep(500);} catch (InterruptedException e) {throw new RuntimeException(e);}
        // 操作完成后清理磁盘
        boolean delete = file.delete();
        LOGGER.info("文件删除: {}", (delete ? "成功" : "失败"));
        // 分片配置文件
        boolean configDelete = new File(config.getConfFilePath().concat(sourceFileName.concat(".conf"))).delete();
        LOGGER.info("配置文件删除: {}", (configDelete ? "成功" : "失败"));
        return AppResult.ok();
    }
}
